package xdu.lz.stage2_design_pattern.chapter17_worker_thread_pattern;

import java.util.Arrays;

public class Channel {

    //自己使用数据实现了一个队列

    private static final int MAX_REQUEST = 100;

    private int head;

    private int tail;

    private int count;

    private final Request[] requestQueue;

    private final WorkerThread[] workerPool;

    public Channel(int workers) {
        this.workerPool = new WorkerThread[workers];
        this.requestQueue = new Request[MAX_REQUEST];
        this.head = 0;
        this.tail = 0;
        this.count = 0;
        this.init();
    }

    private void init() {
        for (int i = 0; i < workerPool.length; i++) {
            workerPool[i] = new WorkerThread("WorkerObserver-"+i,this);
        }
    }

    /**
     * 生产流水线的开关,管理工人怎么去做 ，这是核心！
     */
    public void startWork(){
        Arrays.asList(workerPool).forEach(WorkerThread::start);
    }

    public synchronized void offer(Request request){
        while (this.count >= requestQueue.length){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.requestQueue[tail] = request;
        tail = (tail+1) % requestQueue.length;
        this.count ++;
        //有东西放入流水线了，通知工人干活
        this.notifyAll();
    }

    public synchronized Request poll(){
        while (this.count <=0 ){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        Request request = requestQueue[head];
        this.head = (this.head +1) % requestQueue.length;
        this.count -- ;
        //告诉流水线已经被拿了，可以再放了
        this.notifyAll();
        return request;
    }

}
